﻿/// <reference path="jquery.min.js" />
/// <reference path="jquery.tools.min.js" />
/// <reference path="app.js" />

// 页面处理 ////////////////////////////////////////////////////////////////////
(function (window, jQuery) {
    var $ = jQuery;
    var page = {};
    window.page = page;

    // 基本数据结构 ////////////////////////////////////////////////////////////
    (function () {
        // 定义可自复制的结构所有通过Struct.create创建的对象都可自复制。
        // 自复制后，如果模板对象有onCreate方法，则调用该方法。
        // 自复制时可指定扩展内容，通过一个json来进行扩展，
        // 但扩展内容中定义的onCreate不会在当前自复制完成后执法。
        page.Struct = {
            create: function (exts) {
                var obj = {};
                var onCreate = this.onCreate;
                $.extend(true, obj, this, exts);

                if (typeof onCreate === "function") {
                    onCreate.call(obj);
                }

                return obj;
            }
        };

        page.data = {};

        // 解析field设置
        page.data.Field = page.Struct.create({
            toBoolean: function (value) {
                if (typeof value !== "string" && !value) {
                    return false;
                } else {
                    if (value.match(/\s*(false|no)\s*/i)) {
                        return false;
                    } else {
                        return true;
                    }
                }
            },

            onCreate: function () {
                this.grid.field = this;
            },

            grid: {
                parse: function ($grid) {
                    if (!$grid || $grid.length < 1) {
                        return;
                    }

                    this.width = $grid.attr("width");
                    this.align = $grid.attr("align");

                    return this;
                },
                getAlign: function () {
                    if (!this.align) { return this.field.align; }
                    return this.align;
                },
                configTh: function ($th, isDetail) {
                    if (!$th) { return; }
                    this.configTd($th, isDetail);
                    $th.text(this.field.title);
                    $th.data("name", this.field.name);
                    $th.data("config", this);

                    if (!isDetail) {
                        if (!!this.width) { $th.css("width", this.width); }
                    }

                    return $th;
                },
                configTd: function ($td, isDetail) {
                    if (!$td) { return; }
                    $td.addClass("t_" + this.field.type);
                    if (!isDetail) {
                        $td.addClass("align_" + this.getAlign());
                    } else {
                        $td.data("config", this.field);
                        if ($td.is("td") && !!this.field.def) {
                            var key = $.trim(this.field.def);
                            var value = key.replace(/var:.+?;/g, function (k) {
                                return app.vars.get(k);
                            });

                            $td.data("value", value).text(value);
                        }
                    }
                    return $td;
                }
            },

            tip: {
                content: null,
                isHtml: false,
                makeDiv: function ($div) {
                    if (!$div) {
                        $div = $("<div>");
                    }
                    $div.addClass("tip");
                    if (this.isHtml) {
                        $div.html(this.content);
                    } else {
                        $div.text(this.content);
                    }
                    return $div;
                },
                parse: function ($tip) {
                    this.content = $tip.text();
                    this.isHtml = page.data.Field.toBoolean($tip.attr("html"));
                }
            },

            isReadonly: function () {
                return this.isMarchView(this.readonly);
            },

            isHidden: function () {
                return this.isMarchView(this.hide);
            },

            isMarchView: function (attr) {
                if (typeof attr !== "string") {
                    return false;
                }

                if (!attr) {   // 属性为空字符串，表示不限视图
                    return true;
                }

                if (/true|yes/i.test(attr)) {
                    return true;
                } else if (/false|no/i.test(attr)) {
                    return false;
                } else {
                    return new RegExp(page.view() || "list", "i").test(attr);
                }
            },

            isRequired: function ($field) {
                var r = $field.attr("required");
                if (typeof r !== "string") { return page.config.fields.required; }
                else { return this.toBoolean(r); }
            },

            parse: function ($field) {
                this.name = $field.attr("name");
                this.title = $field.attr("title") || this.name;
                this.type = $field.attr("type") || "";
                this.align = $field.attr("align") || "";
                this.def = $field.attr("default") || "";
                this.length = parseInt($field.attr("length")) || 0;

                this.hide = $field.attr("hide");
                this.readonly = $field.attr("readonly");
                this.required = this.isRequired($field);

                this.tip.parse($field.children("tip"));
                this.grid.parse($field.children("grid"));

                this.parseItems($field);

                return this;
            },

            parseItems: function ($field) {
                var items = $field.find("items");
                if (!items) {
                    return;
                }

                // 如果配置了直接值，保存直接值设置
                var itemArray = [];
                items.children("item").each(function () {
                    var item = $(this);
                    var t = item.text();
                    var v = item.attr("value");
                    if (typeof v === "undefined") { v = t; }
                    itemArray.push({
                        text: t,
                        value: v
                    })
                });
                this.items = itemArray; // 为items赋值

                // 分析action参数
                if (!!items.attr("action")) {
                    this.items.action = items.attr("action");
                } else {
                    this.items.action = "DropDown";
                }

                // 分析是否是子项
                this.items.subOf = items.attr("subof") || null;

                // 分析URL和action参数
                var me = this;
                var combine = page.data.Field.toBoolean(items.attr("combine"));
                if (!!items.attr("url")) {
                    this.items.url = items.attr("url");
                    if (!!this.items.subof) {
                        return;
                    }
                    page.ajaxData(this.items.url, {
                        fi_act: this.items.action
                    }, function ($xml) {
                        me.items = page.tool.getTextValueArray($xml, combine);
                        if (!!me.items) {
                            // 加载完成看是否已经makeEditable了，如果是，再处理一次
                            if (/edit|add/i.test(page.view())) {
                                var td = page.content.find("table.data_edit tr[field=" + me.name + "] td");
                                if (td.length > 0 && td.find("select,input").length > 0) {
                                    page.edit.makeTdEditable(td);
                                }
                            }
                        } else {
                            app.dialog.message("获取数据超时，可能是网络不稳定，请稍后重试。");
                        }
                    });
                }
            }
        });
    })();

    // 页面工具 ////////////////////////////////////////////////////////////////
    (function () {
        page.tool = {
            // 为URL添加随机参数
            randomUrl: function (url) {
                if (url.indexOf("?") < 0) {
                    return url + "?_r=" + Math.random();
                } else {
                    return url + "&_r=" + Math.random();
                }
            },

            ajaxConfig: function (key, url, callback) {
                if (!key) {
                    throw new Error("Key是必须的");
                }

                if (!url) {
                    throw new Error("请指定Ajax数据的URL");
                }

                if (typeof callback != "function") {
                    callback = noop;
                }
                app.ajax(url, function (data, p1, p2, p3) {
                    if (!!data) {
                        var d = $(data);
                        page.config.cache(key, d);
                        callback(d, p1, p2);
                    } else {
                        callback(null, p1, p2, p3);
                    }
                }, "xml");
            },

            ajaxData: function (url, params, callback) {
                if (typeof params === "function") {
                    callback = params;
                    params = undefined;
                }

                if (typeof callback != "function") {
                    callback = noop;
                }

                app.ajax(url, params, function (xml, p1, p2, p3) {
                    if (!!xml) {
                        var $xml = $(xml);
                        var code = parseInt($xml.find("response > code").text());
                        if (code < 0) {
                            if (!app.sysError(code, $xml.find("response > message").text())) {
                                callback(null, p1, p2, p3);
                                return;
                            }
                        }
                        callback($xml, p1, p2);
                    } else {
                        callback(null, p1, p2, p3);
                    }
                }, "xml");
            },

            getTextValueArray: function ($xml, combine) {
                if (!$xml) {
                    return null;
                }

                var r = [];
                $xml.find("datas > data").each(function () {
                    var v = $(this).find("VALUE").text() || $(this).find("value").text();
                    var t = $(this).find("TEXT").text() || $(this).find("text").text();
                    if (combine) { t = v + " : " + t; }
                    r.push({
                        text: t,
                        value: v
                    });
                });
                return r;
            },

            fillSelect: function (select, items, isKeepOldOptions) {
                if (!select) {
                    return;
                }

                if (!isKeepOldOptions) {
                    select.empty();
                }

                if (!items) {
                    return;
                }

                var v = select.data("value");
                var isSelected = (v === undefined);
                for (var i = 0; i < items.length; i++) {
                    var item = items[i];
                    var option = $("<option>").text(item.text || "").val(item.value).appendTo(select);
                    if (!isSelected && item.value == v) {
                        option.attr("selected", true);
                        isSelected = true;
                    }
                }

                select.change();
            },

            makeSubable: function (control, subSelector, url, action) {
                if (control.is("select")) {
                    control.unbind("change.fi_cfg").bind("change.fi_cfg", function () {
                        var v = $(this).children("option:selected").val();
                        if (typeof v === "undefined" || v === "") {
                            return;
                        }

                        var loadSub = function () {
                            var sub = $(subSelector);
                            if (sub.length > 0) {
                                sub.empty().append($("<option>").text("正在载入列表..."));
                                var params = { fi_act: action };
                                params[control.attr("name")] = v;
                                page.ajaxData(url, params, function ($xml) {
                                    page.tool.fillSelect(sub, page.tool.getTextValueArray($xml, true));
                                });
                            } else {
                                setTimeout(loadSub, 100);
                            }
                        }

                        loadSub();
                    }).change();
                }
            }
        };
    })();

    // page.config，所有配置相关的东西都在这里
    (function () {
        page.config = function ($xml) {
            this.cfg = $xml;
            if (!$xml) {
                return;
            }

            // 页面配置
            var pages = {};
            var jPages = $xml.find("pages");
            if (jPages.length > 0) {
                pages.omit = jPages.attr("default");
                if (!pages.omit) { pages.omit = "list"; }
            } else {
                pages.omit = "list";
            }

            $xml.find("pages page").each(function () {
                var key = $(this).attr("view");
                if (!key) { return; }

                var value = {
                    url: $(this).attr("url") || null,
                    html: $.trim($(this).text()) || null
                };

                if (!value.url && !value.html) { return; }

                pages[key] = value;
            });
            this.config.pages = pages;

            // 配置grid_edit
            this.config.gridIcons = (function () {
                var gis = $xml.find("grid_icons");
                if (gis.length === 0) { return []; }

                var gridIcons = [];
                var w = gis.attr("width");
                if (!!w) { gridIcons.width = w; }

                var ro = gis.attr("readonly");
                gridIcons.readonly = (ro == "true");

                gis.find("icon").each(function () {
                    var icon = {
                        icon: $(this).attr("icon"),
                        text: $(this).attr("text"),
                        onclick: $(this).attr("onclick")
                    };
                    log.debug(icon);
                    gridIcons.push(icon);
                });

                return gridIcons;
            })();


            // 字段配置
            var fields = this.config.fields = [];
            var $fs = $xml.find("fields");
            fields.keys = $fs.attr("keys");
            fields.required = page.data.Field.toBoolean($fs.attr("required"));

            // 配置每个字段
            $xml.find("fields > field").each(function () {
                var f = page.data.Field.create().parse($(this));
                fields.push(f);
                fields[f.name] = f;
            });

            // 配置查询条件
            var query = this.config.query = [];
            $xml.find("query item").each(function () {
                var item = $(this);
                var qItem = {
                    "name": item.attr("name") || "",
                    "title": item.attr("title") || "",
                    "default": item.attr("default") || ""
                };
                if (!qItem.name) { return; }
                if (!qItem.title) { qItem.title = qItem.name; }
                query.push(qItem);
            });

            query.getDefaults = function () {
                var r = {};
                for (var i = 0; i < this.length; i++) {
                    var item = this[i];
                    if (!item["default"]) { continue; }
                    r[item.name] = item["default"];
                }
                return r;
            };

            // 配置事件
            var eText = $xml.find("config > events").text();
            if (!!eText) {
                this.config.events = eval(eText);
            }
        };

        $.extend(page.config, {
            caches: {},
            cache: function (key, value) {
                if (!!value) {
                    this.caches[key] = value;
                } else {
                    return this.caches[key];
                }
            },

            getUrl: function (key) {
                if (!page.cfg) {
                    return null;
                }
                var actions = page.cfg.find("config > actions");
                return actions.children(key).attr("url") || actions.attr("url");
            },

            DefaultActions: {
                list: "List",
                get: "Get",
                save: "Save",
                del: "Delete",
                dels: "DeleteMulti"
            },

            getAction: function (key) {
                if (!page.cfg) {
                    return null;
                }

                var actions = page.cfg.find("config > actions");
                var action = actions.children(key).text();
                if (!action) {
                    action = this.DefaultActions[key];
                    var suffix = actions.attr("suffix");
                    if (!!suffix) {
                        action += suffix;
                    }
                }
                return action;
            }
        });
    })();

    // 页面基本方法 ////////////////////////////////////////////////////////////
    (function () {
        $.extend(page, {
            ajaxConfig: function (key, callback) {
                var cachedConfig = this.config.cache(key);
                if (!!cachedConfig) {
                    page.config(cachedConfig);
                    if (typeof callback == "function") {
                        callback(cachedConfig, "r:cache");
                    }
                    return;
                }

                this.tool.ajaxConfig(key,
                    this.tool.randomUrl("view/" + key + ".xml"),
                    function ($xml) {
                        page.config($xml);
                        if (!$xml) {
                            app.dialog.message("加载配置不成功，请稍后重试");
                            app.loading.hide("加载配置不成功，请稍后重试");
                        }
                        callback.apply(null, arguments);
                    });
            },

            ajaxData: function (url, params, callback) {
                this.tool.ajaxData(url, params, callback);
            },

            ajaxAction: function (actionKey, params, callback) {
                var url = this.config.getUrl(actionKey);
                var action = this.config.getAction(actionKey);
                var data = $.extend({
                    fi_act: action
                }, params);
                this.ajaxData(url, data, callback);
            }
        });
    })();

    // 页面控制按钮栏 //////////////////////////////////////////////////////////
    (function () {
        page.ctrlBar = {
            create: function () {
                return $("<div>").addClass("ctrl_bar").disableSelect();
            },
            createButton: function (text) {
                var button = $("<span>").makeButton().text(text || "").hoverable();
                button.get(0).hideFocus = true;
                return button;
            },
            hideButton: function (text) {
                $(".ctrl_bar").find("span.button:contains(" + text + ")").hide();
            },
            showButton: function () {
                $(".ctrl_bar").find("span.button:contains(" + text + ")").show();
            },
            createLink: function (text, href) {
                var link = $("<a>").text(text || "");
                if (!!href) {
                    link.attr("href", href);
                }
                link.get(0).hideFocus = true;
                return link;
            }
        };

        page.onResize = function (mainHeight) {
            if (!mainHeight) {
                mainHeight = window.mainHeight();
            }

            var ctrlBarHeight = $(".ctrl_bar").height() || 0;
            var queryBarHeight = $(".query_bar").height() || 0;
            $(".grid_container").height(mainHeight - ctrlBarHeight
                - ctrlBarHeight - queryBarHeight).css("overflow", "auto");
        };
    })();

    // 事件扩展 ////////////////////////////////////////////////////////////////
    (function () {
        page.postEvent = function (name) {
            if (!page.config.events) {
                return;
            }

            var fun = page.config.events[name];
            var isGlobal = true;
            var e = page.config.events[this.view() || "list"];

            if (!!e) {
                var f = e[name];
                if (typeof f === "function") {
                    fun = f;
                    isGlobal = false;
                }
            }

            if (typeof fun === "function") {
                var args = [];
                if (isGlobal) {
                    args.push(this.view());
                }
                for (var i = 1; i < arguments.length; i++) {
                    args.push(arguments[i]);
                }
                return fun.apply(isGlobal ? page.config.events : e, args);
            }
        };
    })();

    // 数据列表页面 ////////////////////////////////////////////////////////////
    (function () {
        page.loadConfig = function (configKey, callback) {
            callback = callback || noop;
            //            if (configKey in page.config.cache) {
            //                callback(page.config.cache[configKey]);
            //            }

            app.loading.show("正在加载配置：[" + configKey + "]");
            page.ajaxConfig(configKey, function ($xml) {
                if (!$xml) {
                    callback(null);
                    return;
                } else {
                    callback($xml);
                }
            });
        },
        page.list = {
            // 根据Key找到配置页面，创建数据表格
            make: function ($context, configKey, callback) {
                var me = this;
                page.loadConfig(configKey, function () {
                    me.create($context, function (table) {
                        me.fillData(table);
                    });
                });
            },

            // 创建列表页面框架，含上下操作区和表格区域
            createFrame: function ($context) {
                $context.empty();
                var frame = {
                    topBar: page.ctrlBar.create().appendTo($context),
                    tableArea: $("<div>").addClass("grid_container").appendTo($context),
                    bottomBar: page.ctrlBar.create().appendTo($context)
                }

                this.createCtrlBar(frame.topBar);
                this.createCtrlBar(frame.bottomBar);

                page.postEvent("onCreatedFrame");

                return frame;
            },

            createCtrlBar: function (bar) {
                var me = this;

                // 添加按钮
                page.ctrlBar.createButton("添加").appendTo(bar).mousedown(function (e) {
                    var url = page.makeUrl({
                        "view": "add"
                    });
                    page.applyUrl(url);
                    e.stopPropagation();
                });

                // 删除按钮
                page.ctrlBar.createButton("删除").appendTo(bar).mousedown(function (e) {
                    var checkBoxes = page.content.find("table.data_grid tr").find("td:first :checkbox:checked");
                    var rows = checkBoxes.parentsUntil("tr").parent("tr");
                    if (rows.length === 0) {
                        app.dialog.message("您还没有选中需要删除的数据，请先选中再点［删除］按钮。");
                    } else {
                        app.dialog.confirm("您确定要删除你选中的 " + rows.length + " 条数据么？删除后不可恢复，请慎重！",
                            function () {
                                var ids = [];
                                rows.each(function () {
                                    ids.push($(this).data("id"));
                                });

                                var params = {};
                                params[page.config.fields.keys] = ids;

                                page.ajaxAction("dels", params, function (r) {
                                    if (!!r && r.find("response > code").text() === "0") {
                                        app.dialog.message("成功删除所选数据");
                                        page.ctrl.go();
                                    } else {
                                        app.dialog.message("删除所选数据时发生错误，删除失败。");
                                    }
                                });
                            });
                    }
                    e.stopPropagation();
                });

                // 分页按钮
                var pageControl = $("<div>").addClass("page_control");
                page.ctrlBar.createLink("首页").addClass("page_f disabled").data("page", 1).appendTo(pageControl);
                page.ctrlBar.createLink("上页").addClass("page_p disabled").appendTo(pageControl);
                page.ctrlBar.createLink("下页").addClass("page_n disabled").appendTo(pageControl);
                page.ctrlBar.createLink("末页").addClass("page_l disabled").appendTo(pageControl);

                pageControl.children("a").click(function () {
                    me.goPage($(this));
                });

                $("<select>").appendTo(pageControl)
                    .append($("<option>").val(1).text("1/1").attr("selected", true))
                    .change(function () {
                        me.goPage($(this), $(this).find("option:selected").val());
                    });
                pageControl.appendTo(bar);
            },

            goPage: function ($a, p) {
                if ($a.is(".disabled")) {
                    return;
                }

                if (typeof p !== "number") {
                    p = parseInt(p);
                    if (!p) {
                        p = $a.data("page");
                    }
                }

                page.applyUrl(page.makeUrl(page.getParams({ page: p })));
            },

            // 创建查询面板
            createQueryPanel: function (frame, $context) {
                if (!page.config.query || page.config.query.length == 0) {
                    return;
                }

                page.ctrlBar.createButton("查询").prependTo(frame.topBar).mousedown(function (e) {
                    var queryParams = {};
                    $(".query_bar :input").each(function () {
                        var v = $(this).val();
                        if (!v) { return; }
                        queryParams[$(this).attr("name")] = v;
                    });
                    var url = page.makeUrl(queryParams);
                    page.applyUrl(url);
                    e.stopPropagation();
                }).addClass("end_group");

                // 创建查询面板
                var queryBar = $("<div>").addClass("query_bar").insertAfter(frame.topBar);
                var pageParams = page.getParams();
                $.each(page.config.query, function (index, item) {
                    var div = $("<div>");
                    div.text(item.title);
                    var input = $("<input>").appendTo(div).attr("name", item.name);
                    if (!!pageParams[item.name]) {
                        input.val(pageParams[item.name]);
                    }
                    div.appendTo(queryBar);
                });
            },

            // 创建表格结构（Header）
            create: function ($context, callback) {
                var me = this;
                var frame = this.createFrame($context);
                this.createQueryPanel(frame, $context);

                if (typeof callback != "function") {
                    callback = noop;
                }

                // 创建表格
                var $t = $("<table>").addClass("data_grid");
                var $tr = $("<tr>").addClass("header");
                var tableWidth = 0;

                // 添加操作列
                me.createCheckBoxCell(true).appendTo($tr);
                me.createEditCell(true).appendTo($tr);

                // 添加数据列
                $.each(page.config.fields, function (i, field) {
                    if (field.isHidden()) {
                        return;
                    }

                    var $th = field.grid.configTh($("<th>"));
                    var w = parseInt(field.grid.width);
                    if (!!w) {
                        tableWidth += w;
                    }
                    $th.appendTo($tr);
                });
                $tr.appendTo($t);
                $t.appendTo(frame.tableArea);
                $t.attr("min-width", tableWidth);
                if ($t.width() < tableWidth) {
                    $t.width(tableWidth);
                }

                app.loading.hide()
                page.onResize();
                callback($t);
            },

            createCheckBoxCell: function (isHeader) {
                isHeader = !!isHeader;
                var cell = isHeader ? $("<th>") : $("<td>");
                cell.addClass("c_checkbox");
                var checkbox = $("<input type='checkbox'>").appendTo(cell);
                checkbox.get(0).hideFocus = true;

                // 处理checkbox事件，全选状态变更
                if (isHeader) {
                    checkbox.change(function () {
                        var isChecked = $(this).is(":checked");
                        $(this).parentsUntil("table").parent("table")
                            .find("td.c_checkbox :checkbox").attr("checked", isChecked);
                    }).click(function (e) {
                        e.stopPropagation();
                    });

                    // 点击表格与点击checkbox同样效果
                    cell.click(function (e) {
                        var cell = $(this);
                        var isChecked = cell.find(":checkbox").is(":checked");
                        cell.find(":checkbox").attr("checked", !isChecked).change();
                        e.stopPropagation();
                    }).disableSelect();
                } else {
                    checkbox.change(function () {
                        var table = $(this).parentsUntil("table").parent("table");
                        var tdCheckBoxes = table.find("td.c_checkbox :checkbox");
                        var isAllChecked = tdCheckBoxes.length === tdCheckBoxes.filter(":checked").length;
                        table.find("th.c_checkbox :checkbox").attr("checked", isAllChecked);
                    }).click(function (e) {
                        e.stopPropagation();
                    });
                }

                return cell;
            },

            createIconLink: function (icon, text, f) {
                var a = $("<a>").addClass("icon_link").css("background", "url(style/def/" + icon + ")")
                    .attr("href", "javascript:noop()").attr("title", text);
                if (typeof f === "function") { a.click(f); }
                a.hideFocus = true;
                return a;
            },

            createEditCell: function (isHeader) {
                var me = this;
                var cell = !!isHeader ? $("<th>") : $("<td>");
                cell.addClass("c_edit");
                if (!!page.config.gridIcons && !!page.config.gridIcons.width) {
                    cell.css("width", page.config.gridIcons.width + "px");
                }
                if (!isHeader) {
                    if (!!page.config.gridIcons && !!page.config.gridIcons.readonly) {
                        this.createIconLink("view.png", "查看", function (e) {
                            var tr = $(this).parentsUntil("tr").parent("tr");
                            var url = page.makeUrl({
                                "view": "view",
                                "id": tr.data("id")
                            });
                            page.applyUrl(url);
                            e.stopPropagation();
                        }).appendTo(cell);
                    } else {
                        this.createIconLink("edit.png", "编辑", function (e) {
                            var tr = $(this).parentsUntil("tr").parent("tr");
                            var url = page.makeUrl({
                                "view": "edit",
                                "id": tr.data("id")
                            });
                            page.applyUrl(url);
                            e.stopPropagation();
                        }).appendTo(cell);
                    }

                    if (!!page.config.gridIcons) {
                        $.each(page.config.gridIcons, function (i, e) {
                            me.createIconLink(e.icon, e.text, function (evt) {
                                var tr = $(this).parentsUntil("tr").parent("tr");
                                page.postEvent(e.onclick, tr.data("id"));
                                evt.stopPropagation();
                            }).appendTo(cell);
                        });
                    }

                    // var a = $("<a>").attr("href", "javascript:noop()")
                    //     .text("编辑").appendTo(cell);
                    // a.click(function (e) {
                    //     var tr = $(this).parentsUntil("tr").parent("tr");
                    //     var url = page.makeUrl({
                    //         "view": "edit",
                    //         "id": tr.data("id")
                    //     });
                    //     page.applyUrl(url);
                    //     e.stopPropagation();
                    // });
                }
                return cell;
            },

            initClickRow: function (row) {
                row.click(function (e) {
                    var row = $(this);
                    var isChecked = row.find(":checkbox").is(":checked");
                    row.find(":checkbox").attr("checked", !isChecked).change();
                    e.stopPropagation();
                });
            },

            // 填充表格数据
            fillData: function ($table) {
                var me = this;

                app.loading.show("正在加载数据表格");
                var listUrl = page.config.getUrl("list");
                var listAction = page.config.getAction("list");

                var map = {};
                // 找出除了前两列（序号和编辑）之外的所有列
                var thList = $table.find("tr:first th:gt(1)").each(function () {
                    var th = $(this);
                    map[th.data("name")] = th.index();
                });

                var trTempl = $("<tr>");
                // 添加数据列
                for (var i = 0; i < thList.length; i++) {
                    var th = thList.eq(i);
                    var td = $("<td>");
                    if (!!th.data("config")) {
                        th.data("config").configTd(td);
                    }
                    td.appendTo(trTempl);
                }

                // 创建行
                var createRow = function () {
                    var tr = trTempl.clone(true);
                    me.createEditCell().prependTo(tr);
                    me.createCheckBoxCell().prependTo(tr);
                    me.initClickRow(tr);
                    tr.hoverable();
                    return tr;
                };

                var params = $.extend(page.config.query.getDefaults(),
                    page.getParams({ fi_act: listAction }))
                page.ajaxData(listUrl, params, function ($xml) {
                    if (!!$xml && $xml.find("response > code").text() === "0") {
                        var keys = page.config.fields.keys;
                        var data = $xml.find("response > data");
                        data.find("datas > data").each(function () {
                            var d = $(this);
                            var id = d.children(keys).text();
                            var fs = d.children();
                            var tr = createRow();
                            tr.data("id", id);
                            for (var i = 0; i < fs.length; i++) {
                                var key = fs.get(i).tagName;
                                var index = map[key];
                                tr.children().eq(index).text(fs.eq(i).text());
                            }
                            tr.appendTo($table);
                        });

                        me.setPage(data.children("page_info"));
                    }

                    page.postEvent("onLoadData");
                    if ($table.width() > $table.parent().width()) {
                        $table.parent().height($table.height() + 38);
                    }
                    app.loading.hide();
                    page.onResize();
                });
            },

            setPage: function ($page) {
                var total = parseInt($page.children("total").text()) || 1;
                if (total < 1) { total = 1; }

                var page = parseInt($page.children("page").text()) || 1;
                if (page < 1) { page = 1; }

                // 翻页列表
                var pageList = $(".page_control select").empty();
                for (var i = 1; i <= total; i++) {
                    var options = $("<option>").val(i).text(i + "/" + total);
                    options.appendTo(pageList);
                }
                pageList.find("option[value=" + page + "]").attr("selected", true);

                // 页面按钮
                if (page > 1) {
                    $(".page_control .page_f").removeClass("disabled");
                    $(".page_control .page_p").removeClass("disabled").data("page", page - 1);
                }
                if (page < total) {
                    $(".page_control .page_n").removeClass("disabled").data("page", page + 1);
                    $(".page_control .page_l").removeClass("disabled").data("page", total);
                }
            }
        };
    })();

    // 编辑页面 ////////////////////////////////////////////////////////////////
    (function () {
        page.edit = {
            make: function ($content, configKey, callback) {
                var me = this;
                page.loadConfig(configKey, function () {
                    me.create($content, function (table) {
                        // 触发事件
                        page.postEvent("onLoadConfig", page.config.cache[configKey], table);
                        page.onResize();

                        // 加载数据
                        if (page.view() === "add") {
                            me.makeEditable(table);
                        } else {
                            me.fillData(page.config.cache[configKey], table, function () {
                                if (page.view() === "edit") {
                                    me.makeEditable(table);
                                }
                            });
                        }
                    });
                });
            },

            // 创建列表页面框架，含上下操作区和表格区域
            createFrame: function ($context) {
                $context.empty();
                var frame = {
                    topBar: page.ctrlBar.create().appendTo($context),
                    tableArea: $("<div>").addClass("grid_container").appendTo($context),
                    bottomBar: page.ctrlBar.create().appendTo($context)
                }

                this.createCtrlBar(frame.topBar);
                this.createCtrlBar(frame.bottomBar);

                page.postEvent("onCreatedFrame");

                return frame;
            },

            // 创建工具栏
            createCtrlBar: function (bar) {
                var listButton = page.ctrlBar.createButton("返回列表").mousedown(function () {
                    var url = page.makeUrl();
                    page.applyUrl(url);
                }).appendTo(bar).addClass("end_group");

                if (page.view().match(/edit/i)) {
                    listButton.removeClass("end_group");
                    page.ctrlBar.createButton("新增").mousedown(function () {
                        page.applyUrl(page.makeUrl({
                            "view": "add"
                        }));
                    }).appendTo(bar).addClass("end_group");
                }

                page.ctrlBar.createButton("保存").mousedown(function () {
                    if (!page.edit.verifyAll()) {
                        app.dialog.message("填写的数据中有不正确的数据，请修正之后再保存。",
                            function () {
                                $("table.data_edit .err:visible:first")
                                    .prevUntil("input").andSelf().prev("input").focus();
                            });
                    } else {
                        var data = page.edit.getInputs();
                        var newData = page.postEvent("onSaving", data);
                        if (!!newData) {
                            data = newData;
                        }
                        var url = page.config.getUrl("save");
                        var action = page.config.getAction("save");

                        app.loading.show("正在保存数据，请稍候...");
                        page.ajaxData(url, $.extend({
                            fi_act: action,
                            m: page.view()
                        }, data), function ($xml) {
                            if (!!$xml && $xml.find("response > code").text() === "0") {
                                app.dialog.message("保存成功", function () {
                                    page.postEvent("onSaved", true);
                                });
                            } else {
                                app.dialog.message("保存失败", function () {
                                    page.postEvent("onSaved", false);
                                });
                            }
                            app.loading.hide();
                        });
                    }
                }).appendTo(bar);

                if (page.view().match(/edit/i)) {
                    page.ctrlBar.createButton("删除").mousedown(function () {
                        app.dialog.confirm("数据删除后将不可恢复，您确定要删除当前这条数据吗？",
                            function () {
                                var params = {};
                                params[page.config.fields.keys] = page.id();
                                page.ajaxAction("del", params, function (r) {
                                    if (!!r && r.find("response > code").text() === "0") {
                                        app.dialog.message("成功删除当前数据");
                                    } else {
                                        app.dialog.message("删除当前数据时发生错误，删除失败。");
                                    }
                                });
                            });
                    }).appendTo(bar);
                }
            },

            create: function ($content, callback) {
                if (typeof callback !== "function") {
                    callback = noop;
                }

                var frame = this.createFrame($content);

                // 判断是否是自定义页面
                var pageConfig = page.config.pages["edit"];
                if (!!pageConfig) {
                    var loadHtml = function (html) {
                        if (!html) {
                            return;
                        }

                        var c = $(html).appendTo(frame.tableArea);
                        app.loading.hide();
                        callback(c);
                    };

                    if (!!pageConfig.html) {
                        loadHtml(pageConfig.html);
                    } else {
                        app.ajax(pageConfig.url, "html", function (html) {
                            pageConfig.html = html;
                            loadHtml(pageConfig.html);
                        });
                    }
                    return;
                }

                // 创建编辑表格
                var $t = $("<table>").addClass("data_edit");
                $.each(page.config.fields, function (i, field) {
                    if (field.isHidden()) {
                        return;
                    }
                    var $tr = $("<tr>").data("config", field).attr("field", field.name);
                    var $th = field.grid.configTh($("<th>"), true);
                    $th.appendTo($tr);
                    field.grid.configTd($("<td>"), true).appendTo($tr);
                    $tr.appendTo($t);
                });

                $t.appendTo(frame.tableArea);

                (function () {
                    var clientWidth = frame.tableArea.width();
                    clientWidth -= parseInt($t.css("margin-left"));
                    clientWidth -= parseInt($t.css("margin-right"));
                    clientWidth -= parseInt(frame.tableArea.css("padding-left"));
                    clientWidth -= parseInt(frame.tableArea.css("padding-right"));
                    if ($t.width() < clientWidth) {
                        $t.width(clientWidth);
                    }
                })();

                app.loading.hide();
                callback($t);
            },

            fillData: function (xml, table, callback) {
                callback = callback || noop;
                var me = this;

                var params = {};
                params[page.config.fields.keys] = page.id();
                app.loading.show("正在加载数据，请稍候...");
                page.ajaxAction("get", params, function (r) {
                    page.edit.data = null;
                    if (!!r) {
                        if (r.find("response > code").text() === "0") {
                            page.edit.data = r.find("response > datas > data:first");
                            me.fill(page.edit.data, table);
                        } else {
                            me.fill(null);
                        }

                        page.postEvent("onLoadData", r, page.content.find("table.data_edit"));
                    } else {
                        me.fill(null);
                        page.postEvent("onLoadData", null, page.content.find("table.data_edit"));
                    }
                    callback();
                    app.loading.hide();
                });
            },

            fill: function (data, table) {
                if (!data) {
                    app.dialog.message("加载数据失败，请稍后重试！若有输入参数，请检查输入是否正确。");
                    return;
                }

                this.idValue = data.find(page.config.fields.keys).text();

                data.children().each(function () {
                    var field = this.tagName;
                    var td = table.find("td[field=" + field + "]");
                    if (td.length < 1) {
                        td = table.find("tr[field=" + field + "]").children("td");
                    }
                    td.data("value", $(this).text()).text($(this).text());
                });
            },

            getInputs: function () {
                var data = {};
                page.content.find("table.data_edit tr").each(function () {
                    $(this).find("td").each(function () {
                        var config = $(this).data("config");
                        if (!config || !config.isReadonly()) { return; }
                        data[config.name] = $(this).text();
                    });

                    var inputs = $(this).find("input");
                    if (inputs.length > 0) {
                        inputs.each(function () {
                            if ($(this).is(":checkbox") || $(this).is(":radio")) {
                                if (!$(this).attr("checked")) {
                                    return;
                                }
                            }

                            var name = $(this).attr("name");
                            if (!data[name]) {
                                data[name] = $(this).val();
                            } else if ($.isArray(data[name])) {
                                data[name].push($(this).val());
                            } else {
                                var v = data[name];
                                data[name] = [
                                    v,
                                    $(this).val()
                                ];
                            }
                        });
                    } else {
                        $("select").each(function () {
                            var s = $(this);
                            var name = s.attr("name");
                            var v = s.children("option:selected").val();
                            if (typeof v !== "undefined") {
                                data[name] = v;
                            }
                        });
                    }
                });

                if (/edit/.test(page.view())) {
                    data[page.config.fields.keys] = page.id();
                }

                return data;
            },

            makeTdEditable: function (td) {
                var config = td.data("config");
                if (!config) {
                    return;
                }

                if (!!config && config.isReadonly()) {
                    td.addClass("readonly");
                    td.attr("name", config.name);
                    return;
                }

                var value = td.data("value");
                var input;
                switch (config.type.toLowerCase()) {
                    case "select":
                        input = this.createSelect(td, config, value);
                        break;
                    case "radio":
                        input = this.createRadios(td, config, value);
                        break;
                    case "checkbox":
                        input = this.createCheckboxes(td, config, value);
                        break;
                    default:
                        input = this.createInput(td, config, value);
                        break;
                }

                page.postEvent("onCreatedControl", input);

                // 输入框激活时显示tip信息
                if (!!config.tip.content) {
                    config.tip.makeDiv().appendTo(td).hide();
                }
                input.focus(function () {
                    td.select().next(".tip").show();
                }).blur(function () {
                    td.next(".tip").hide();
                }).unbind("mouseup.fi").bind("mouseup.fi", function (e) {
                    e.stopPropagation();
                });
            },

            makeEditable: function (table) {
                var r = page.postEvent("onBeforeEditable", table);
                if (r === false) {
                    return;
                }

                var me = this;
                table.find("td").each(function () {
                    me.makeTdEditable($(this));
                });
                page.postEvent("onMadeEditable", table);
                table.find("td :text:not(.disabled):first").focus();
            },

            createInput: function (context, config, value) {
                var input = $("<input type='text'>").val(value);
                input.addClass(context.attr("class"));

                if (!!config.length) {
                    input.attr("maxlength", config.length);
                }

                // 鼠标点击表格单元的时候也会激活其中的输入框
                $(this).unbind("mouseup.fi").bind("mouseup.fi", function () {
                    $(this).children("input").focus();
                });

                // 如果是日期，配置为日期选择
                if (input.is(".t_date")) {
                    input.makeDateInput();
                }

                // 配置验证
                app.validator.init(input);
                input.attr("name", config.name)
                    .addClass($(this).attr("class"))
                    .data("config", config).appendTo(context.empty());

                return input;
            },

            createSelect: function (context, config, value) {
                var select = $("<select>").attr("name", config.name)
                    .data("config", config).addClass(context.attr("class"));
                select.data("value", value);

                if (!!config.items) {
                    page.tool.fillSelect(select, config.items);
                } else {
                    $("<option>").text("正在加载列表...").appendTo(select);
                }

                select.appendTo(context.empty());

                return select;
            },

            createRadios: function (context, config, value) {
                context.empty();
                for (var i = 0; i < config.items.length; i++) {
                    var item = config.items[i];
                    var id = config.name + "_" + item.value;
                    var radio = $("<input type='radio'>").val(item.value)
                        .attr("name", config.name).attr("id", id)
                        .data("config", config);
                    radio.get(0).hideFocus = true;
                    if (item.value === value) {
                        radio.attr("checked", true);
                    }
                    var label = $("<label>").text(item.text)
                        .attr("for", id);
                    label.get(0).hideFocus = true;

                    radio.appendTo(context);
                    label.appendTo(context);
                }

                if (context.children(":checked").length == 0) {
                    context.children().first().attr("checked", true);
                }

                return context.children();
            },

            createCheckboxes: function () {
            },

            verifyAll: function () {
                $("table.data_edit input").change();
                if (page.postEvent("onVerify") === false) {
                    return false;
                }
                return $("table.data_edit .err:visible").length === 0;
            }
        };
    })();

    (function () {
        page.query = {
            make: function (jContent, configKey, callback) {
                var me = this;
                page.loadConfig(configKey, function () {
                    me.create(jContent);
                });
            },

            create: function (content) {
                var pageConfig = page.config.pages["query"];
                if (!!pageConfig) {
                    var loadHtml = function (html) {
                        if (!html) {
                            return;
                        }

                        var c = $(html).appendTo(content);
                        app.loading.hide();
                    };

                    if (!!pageConfig.html) {
                        loadHtml(pageConfig.html);
                    } else {
                        app.ajax(pageConfig.url, "html", function (html) {
                            pageConfig.html = html;
                            loadHtml(pageConfig.html);
                        });
                    }
                    return;
                } else {
                    alert("没有配置查询页面");
                }
            }
        };
    })();

    // 页面地址解析和控制 //////////////////////////////////////////////////////
    (function () {
        $.extend(page, {
            params: {},
            getParams: function (ext) {
                var p = $.extend({}, this.params);
                delete p["key"];
                return $.extend(p, ext);
            },
            key: function () {
                return this.params["key"];
            },
            id: function () {
                return this.params["id"];
            },
            view: function () {
                var view = this.params["view"];
                if (!view) {
                    var defaultView = page.config.pages ? page.config.pages.omit : null;
                    if (!!defaultView) { view = defaultView; }
                    return defaultView;
                }

                return $.trim(view).toLowerCase();
            },
            makeUrl: function (key, params) {
                if (!!key && typeof key !== "string") {
                    params = key;
                    key = null;
                }
                key = key || page.key();

                var url = "app.html#" + key;
                if (!!params) {
                    var ps = $.param(params).replace("&", "/");
                    if (!!ps) {
                        url += "/" + ps;
                    }
                }

                return url;
            },
            applyUrl: function (url) {
                window.location.href = url;
                this.ctrl.go();
            },
            ctrl: {
                // 调用该函数来解析URL并执行相应的操作。
                go: function () {
                    if (!!page.config && !!page.config.pages) {
                        page.config.pages.omit = null;
                    }
                    page.params = {};
                    this.parseUrl();
                },

                // URL中#号后面的部分作为参数解析，参数间用/号分隔
                // 第1个参数是Key
                // 之后的参数是键值对，有键无值（无=号）则为其赋值为true
                parseUrl: function () {
                    url = window.location.href;
                    if (!url.match(/#.+/)) {
                        return;
                    }

                    var params = url.replace(/.+?#/, "").split("/");
                    page.params["key"] = params[0];
                    this.parseParams(params);
                    this.invoke();
                },

                // 解析除Key以外的参数，按键值对保存在page.params中
                parseParams: function (params) {
                    for (var i = 1; i < params.length; i++) {
                        var tokens = params[i].split("=", 2);
                        var key = $.trim(tokens[0]).toLowerCase();
                        key = decodeURI(key);
                        if (tokens.length < 2) {
                            page.params[key] = true;
                        } else {
                            page.params[key] = decodeURI(tokens[1]);
                        }
                    }
                },

                // 根据URL的解析结果刷新页面
                invoke: function () {
                    var me = this;
                    if (!page.key()) {
                        return;
                    }

                    // 根据view参数来加载列表页面或编辑页面
                    var view = page.view();
                    if (!view) {
                        setTimeout($.proxy(me, "invoke"), 200);
                    }

                    switch (view) {
                        case "list":
                            page.list.make(page.content, page.key());
                            break;
                        case "edit": case "add": case "view":
                            page.edit.make(page.content, page.key());
                            break;
                        case "query":
                            page.query.make(page.content, page.key());
                            break;
                        default:    // 默认当列表处理
                            page.list.make(page.content, page.key());
                            break;
                    }
                }
            }
        });
    })();

    // 页面初始化 //////////////////////////////////////////////////////////////
    (function () {
        page.loadUser = function () {
            var me = this;
            app.loading.show("正在初始化应用，请稍候……");
            this.ajaxData("core/bll/税务机关和人员.ashx", {
                fi_act: "GetLoginState"
            }, function ($xml) {
                if (!!$xml) {
                    if ($xml.find("response > code").text() === "0") {
                        app.setUser($xml);
                        app.init();
                        me.init();
                        app.loading.hide();
                        me.ctrl.go();
                    } else {
                        app.sysError(-127);
                    }
                }
            });
        },

        page.init = function () {
            this.content = $("div.content_div");

            $(document).mouseup(function () {
                if (!!window.mouseDownObject) {
                    window.mouseDownObject.removeClass("down");
                    window.mouseDownObject = null;
                }
            });
        };
    })();

    // 执行初始化 //////////////////////////////////////////////////////////////
    $(function () {
        page.loadUser();
    });
})(window, jQuery);
